package fr.imag.adele.cprobes.impl;

import java.util.Dictionary;
import java.util.Hashtable;
import java.util.StringTokenizer;

import org.osgi.framework.BundleContext;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;

import fr.imag.adele.cprobes.services.DataCollector;
import fr.imag.adele.cprobes.services.Probe;
import fr.imag.adele.cprobes.util.DataEvent;
import fr.imag.adele.cprobes.util.DataSet;

/**
 * The standard implementation of the DataCollector Service.
 * It used to collect data events that corresponds to a configured set of topics (or resources).
 * 
 * @author Bassem DEBBABi
 *
 */
public class StandardDataCollector implements DataCollector, EventHandler {
	private Probe 			m_probe;						// the parent probe
	private String	 		m_requiredResources;			// indicates which resources can be collected by the probe		
	private DataSet 		m_localDataSet = new DataSet();	// a local depository to collect the events until
															// that the scheduler calls the process method of the probe.
	private BundleContext 	m_bundleContext;				// the Bundle context object (OSGi). Used to register a event subscriber
	
	/**
	 * Constructor
	 * Used to retrieve the BundleContext
	 * @param bc BundleContext
	 */
	public StandardDataCollector(BundleContext bc){
		this.m_bundleContext = bc;		
	}														
	/**
	 * return the collected data events, and remove all the collected events 
	 * to receive new ones.
	 * @return the collected data events.
	 */
	public DataSet getCollectedData() {
		DataSet dataSet = new DataSet();
		for (int i=0; i<m_localDataSet.size();i++){
			dataSet.add(m_localDataSet.getDataEvent(i));			
		}
		m_localDataSet.removeAllEvents();	
		return dataSet;
	}	
	/**
	 * called when receiving an event that corresponds to the requested topics
	 * @param event OSGi event
	 */
	public void handleEvent(Event event) {		
		DataEvent dataEvent = new DataEvent(event.getProperty(DataEvent.CP_EVENT_RESOURCE).toString(),
				event.getProperty(DataEvent.CP_EVENT_SOURCE).toString(),
				event.getProperty(DataEvent.CP_EVENT_TIMESTAMP).toString(),
				event.getProperty(DataEvent.CP_EVENT_VALUE),
				event.getProperty(DataEvent.CP_EVENT_UNIT).toString(),null);
		getLocalDataSet().add(dataEvent);
		if (getProbe()!=null && getProbe().getScheduler() != null){
			getProbe().getScheduler().notify(dataEvent);
		} else {
			//System.out.println("No Scheduler found!");
		}
	}
	/**
	 * Called when the DataCollector instance started
	 */
	public void starting(){
		Dictionary dico = new Hashtable();				
		String[] resources = getRequiredResources();		
		dico.put(EventConstants.EVENT_TOPIC, resources);		
		m_bundleContext.registerService(EventHandler.class.getName(), this, dico);		
	}
	/**
	 * Called when the DataCollected instance stopped
	 */
	public void stoping(){
		
	}

	//// GETTERS and SETTERS
	
	public void setProbe(Probe probe) {
		this.m_probe = probe;
	}
	public Probe getProbe() {
		return m_probe;
	}
	/**
	 * get the list of the required resources of the probe
	 * @return list of required resources
	 */
	public String[] getRequiredResources() {
		// eliminate espaces
		StringTokenizer st = new StringTokenizer(m_requiredResources," ",false);
		String t="";
		while (st.hasMoreElements()) t += st.nextElement();
		
		// split ro list of tokens
		String[] resources = t.split(",");
		/*String[] result;
		if (resources != null && resources.length > 0){
			result = new String[resources.length];
			// eliminate sources
			for (int i=0; i<resources.length; i++) {
				StringTokenizer st2 = new StringTokenizer(resources[i], "/" ,false);				
				
			}
		}*/
		return resources;
	}
	public void setRequiredResources(String resources) {
		m_requiredResources = resources;
	}
	public DataSet getLocalDataSet() {
		return m_localDataSet;
	}
	public void setLocalDataSet(DataSet dataSet) {
		m_localDataSet = dataSet;
	}
	
	////
	
}
